Skip to content

feat: add changeMeasurementColor command to update annotation colors …#6092

Open
TalalEmara wants to merge 6 commits into
OHIF:masterfrom
TalalEmara:feat/measurement-color-fix
Open

feat: add changeMeasurementColor command to update annotation colors …#6092
TalalEmara wants to merge 6 commits into
OHIF:masterfrom
TalalEmara:feat/measurement-color-fix

Conversation

@TalalEmara

@TalalEmara TalalEmara commented Jun 18, 2026

Copy link
Copy Markdown

…via dialog and extend MeasurementService to support color persistence

Context

This PR addresses a bug where the "Change Color" context menu option for measurements was completely unresponsive because the underlying command was not fully implemented.

Fixes #6059

Changes & Results

  • Added the changeMeasurementColor command to extensions/cornerstone/src/commandsModule.ts.
  • Wired the command to use uiDialogService to open the colorPickerDialog.
  • Extended MeasurementService to ensure the updated color persists in the measurement state.

Results:

  • Before: Clicking "Change Color" did nothing.
  • After: Clicking "Change Color" opens a color picker dialog. Selecting a new color instantly updates the annotation on the canvas and persists
Screenshot from 2026-06-18 16-07-48 Screenshot from 2026-06-18 16-08-01 Screenshot from 2026-06-18 16-08-10

.
Screenshot from 2026-06-18 16-08-16

Testing

Open any study in the Basic Viewer.
2. Select a measurement tool (e.g., Length or Angle) and draw an annotation on the image.
3. Open the right-side Measurement Panel.
4. Click the three dots (...) next to the measurement and select Change Color.
5. Select a new color from the dialog and click Save.
6. Verify that the measurement on the canvas immediately updates to the new color.

Checklist

PR

  • My Pull Request title is descriptive, accurate and follows the
    semantic-release format and guidelines.

Code

  • My code has been well-documented (function documentation, inline comments,
    etc.)

Public Documentation Updates

  • The documentation page has been updated as necessary for any public API
    additions or removals.

Tested Environment

  • [] OS: linux ubuntu 22
  • [] Node version: v24.17.0
  • [] Browser: Mozila firefox 151.0.2

Summary by CodeRabbit

  • New Features
    • Added an interactive option to change a measurement’s color via a color picker dialog.
  • Enhancements
    • Improved measurement color handling so new and updated measurements consistently apply the selected color styling.
    • Ensured color values default correctly and alpha transparency is interpreted properly when rendering measurement annotations, with an immediate refresh after edits.
  • Testing
    • Updated measurement test fixtures to include color data.

Greptile Summary

This PR implements the previously unresponsive "Change Color" context menu option for measurements by adding a changeMeasurementColor command, wiring it to a color picker dialog, and extending MeasurementService to persist the chosen color across viewport lifecycle events.

  • changeMeasurementColor command (commandsModule.ts): opens colorPickerDialog, converts the picked RGBA to a color array, updates MeasurementService, calls setAnnotationStyles, and forces a re-render.
  • Color persistence (MeasurementService.ts): addOrUpdate now carries color forward from the previous measurement state; a new updateColorMeasurement method mutates the stored color and broadcasts MEASUREMENT_UPDATED.
  • Style reapplication (initMeasurementService.ts): new MEASUREMENT_ADDED subscriber and an uncommented block in MEASUREMENT_UPDATED reapply the stored color via setAnnotationStyles on every add/update cycle.

Confidence Score: 4/5

The color picker dialog works correctly, but the yellow fallback in addOrUpdate will make every annotation drawn without a custom color render yellow instead of the tool's native default.

The hardcoded [255, 255, 0, 255] default stored by addOrUpdate is always truthy, so the if(color) guard in the MEASUREMENT_ADDED subscriber never skips style application for un-colored annotations — all newly drawn annotations are forced to yellow, overriding Cornerstone's per-tool default colors for every user regardless of whether they have ever changed a measurement color.

platform/core/src/services/MeasurementService/MeasurementService.ts — the yellow fallback on line 546 needs to be removed or changed to undefined so the if(color) guards in initMeasurementService work as intended.

Important Files Changed

Filename Overview
platform/core/src/services/MeasurementService/MeasurementService.ts Adds updateColorMeasurement() and a color field to addOrUpdate(); the yellow fallback [255,255,0,255] will be stored for every un-colored measurement, causing a default-color regression via the MEASUREMENT_ADDED subscriber.
extensions/cornerstone/src/commandsModule.ts Adds changeMeasurementColor command wired to colorPickerDialog; setAnnotationStyles is called twice per save (once directly, once via MEASUREMENT_UPDATED subscriber), but otherwise the flow is correct.
extensions/cornerstone/src/initMeasurementService.ts Uncomments color application in MEASUREMENT_UPDATED, adds MEASUREMENT_ADDED subscriber, and applies color in RAW_MEASUREMENT_ADDED; all rely on if(color) guard that is defeated by the yellow default in addOrUpdate.
platform/core/src/services/MeasurementService/MeasurementService.test.js Test fixture updated to include color and isDirty fields; straightforward alignment with the updated addOrUpdate shape.

Reviews (5): Last reviewed commit: "Merge branch 'master' into feat/measurem..." | Re-trigger Greptile

…via dialog and extend MeasurementService to support color persistence
@netlify

netlify Bot commented Jun 18, 2026

Copy link
Copy Markdown

Deploy Preview for ohif-dev ready!

Name Link
🔨 Latest commit 3cf6d52
🔍 Latest deploy log https://app.netlify.com/projects/ohif-dev/deploys/6a47ed81b589de0008bece8f
😎 Deploy Preview https://deploy-preview-6092--ohif-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5bf2f049-6430-4566-a2ad-828bddf529d4

📥 Commits

Reviewing files that changed from the base of the PR and between 9ea3f75 and 3cf6d52.

📒 Files selected for processing (2)
  • extensions/cornerstone/src/commandsModule.ts
  • extensions/cornerstone/src/initMeasurementService.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • extensions/cornerstone/src/commandsModule.ts
  • extensions/cornerstone/src/initMeasurementService.ts

📝 Walkthrough

Walkthrough

This PR adds a measurement color-change command, persists RGBA color on measurements, and updates Cornerstone annotation styling when measurement colors are added or changed.

Changes

Measurement Color Change Feature

Layer / File(s) Summary
Color preservation in MeasurementService
platform/core/src/services/MeasurementService/MeasurementService.ts, platform/core/src/services/MeasurementService/MeasurementService.test.js
annotationToMeasurement now sets color using measurement.color, then oldMeasurement?.color, then [255, 255, 0, 255]. updateColorMeasurement gains JSDoc, and the measurement test fixture includes color and isDirty.
Color styling in Cornerstone tools events
extensions/cornerstone/src/initMeasurementService.ts
connectMeasurementServiceToTools now includes MEASUREMENT_ADDED, and the MEASUREMENT_UPDATED, MEASUREMENT_ADDED, and RAW_MEASUREMENT_ADDED paths conditionally apply annotation.config.style.setAnnotationStyles(..., { color: 'rgba(...)' }) when measurement color exists.
changeMeasurementColor action
extensions/cornerstone/src/commandsModule.ts
Adds actions.changeMeasurementColor to load a measurement by uid, open the color picker with the current RGBA value, save the selected color back through measurementService.updateColorMeasurement, update annotation styles, and render. Registers the command in definitions.

Estimated code review effort: 2 (Simple) | ~12 minutes

Sequence Diagram(s)

sequenceDiagram
  participant UI
  participant actions.changeMeasurementColor
  participant measurementService
  participant colorPickerDialog
  participant renderingEngine

  UI->>actions.changeMeasurementColor: changeMeasurementColor({ uid })
  actions.changeMeasurementColor->>measurementService: getMeasurement(uid)
  actions.changeMeasurementColor->>colorPickerDialog: open with current RGBA color
  colorPickerDialog-->>actions.changeMeasurementColor: save selected RGBA color
  actions.changeMeasurementColor->>measurementService: updateColorMeasurement(uid, colorArray)
  actions.changeMeasurementColor->>renderingEngine: render()
Loading

Poem

Poem

A color once silent now travels through the flow,
From measurement state to annotations' glow.
Pick, save, and render — the hues now align,
One click paints the measurement in time.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, specific, and matches the main change: implementing measurement color updates.
Description check ✅ Passed The description includes context, changes, testing, and checklist items with the linked issue reference.
Linked Issues check ✅ Passed The PR implements the Change Color flow and immediate color persistence required by issue #6059.
Out of Scope Changes check ✅ Passed The changed files all support the measurement color feature and related persistence behavior.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread extensions/cornerstone/src/commandsModule.ts Outdated
Comment thread extensions/cornerstone/src/commandsModule.ts Outdated
Comment thread extensions/cornerstone/src/commandsModule.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@extensions/cornerstone/src/commandsModule.ts`:
- Around line 695-702: Add a guard check before accessing the color array in the
measurement object. Before the line that assigns color to a constant, verify
that measurement.color exists and is a valid array with the required indices. If
the color is missing or invalid, either provide a default color value or return
early from the function with appropriate handling. This prevents array index
out-of-bounds errors when creating the rgbaColor object with properties r, g, b,
and a.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 83f95af4-aa8e-46c3-817e-6f480e10dabe

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2d53f and e060ea8.

📒 Files selected for processing (2)
  • extensions/cornerstone/src/commandsModule.ts
  • platform/core/src/services/MeasurementService/MeasurementService.ts

Comment thread extensions/cornerstone/src/commandsModule.ts Outdated
TalalEmara and others added 5 commits June 18, 2026 17:18
Problem:
1. Unguarded access on `measurement.color` caused a silent crash (TypeError) for older measurements that lacked a color field.
2. The alpha channel was silently dropped during CSS string construction, breaking transparency.
3. Custom colors were lost when viewports were rebuilt (e.g., navigating away and back) because `setAnnotationStyles` was not re-called during annotation reload, causing them to render with the default color despite the custom color remaining in state.

Solution:
- Added a fallback default array (`?? [255, 255, 0, 255]`) to prevent crashes on measurements without existing color data.
- Updated the CSS color string generator to use `rgba()` to properly apply the alpha channel to the canvas.
- Synced Cornerstone's style manager with OHIF's `MeasurementService` during all lifecycle events:
  - `MEASUREMENT_ADDED`: Re-applies saved colors via `setAnnotationStyles` when viewports rebuild.
  - `RAW_MEASUREMENT_ADDED`: Restores colors when annotations are initially hydrated.
  - `MEASUREMENT_UPDATED`: Restored the style update block to gracefully sync RGBA colors back to the Cornerstone renderer on changes.
@TalalEmara

Copy link
Copy Markdown
Author

Just a friendly ping on this PR. Let me know if there is anything else you need from me to get this reviewed and merged. Thanks!"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Change Color feature not working for measurements

1 participant